home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / Papers / C++ Exceptions / µShell / Core Utilities / Object.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-12  |  4.6 KB  |  209 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        Object.h
  3.  
  4.     Contains:    Support for Base and Reference Counted Objects
  5.     Written by: Steve Sisak
  6.     Copyright:    © 1996 by Steve Sisak, all rights reserved.
  7.  */
  8.  
  9. #ifndef __OBJECT__
  10. #define __OBJECT__
  11. #pragma once
  12.  
  13. #ifndef __LANGUAGEFEATURES__
  14. #include "LanguageFeatures.h"
  15. #endif
  16. #ifndef __CLASSDESC__
  17. #include "ClassDesc.h"
  18. #endif
  19. #ifndef __EXCEPTIONS__
  20. #include "Exceptions.h"
  21. #endif
  22. #ifndef __TYPES__
  23. #include <Types.h>
  24. #endif
  25.  
  26. //----------------------------------------------------------------------------
  27. // TObject - base class for dynamically allocated objects - also has stub
  28. // support for reference counting
  29. //
  30. //    I've decided to incorporate the reference count directly instead of as
  31. //    a mix-in as the field itself is no larger than a pointer to the base
  32. //    class and it can be useful in debugging even with stack-based objects
  33. //
  34. //----------------------------------------------------------------------------
  35.  
  36. class TObject
  37. #if qObjectInspector
  38.     : public ClassDesc::ObjectRef
  39. #endif
  40. {
  41.     DeclareClassNoBaseAbstract();
  42.  
  43. protected:
  44.     long                fReferenceCount;
  45.  
  46. #if qDebug
  47.     void*                fBaseAddress;
  48.     char*                fClassName;            
  49.  
  50.     inline TObject() : fReferenceCount(0), fBaseAddress(nil), fClassName(nil) {}
  51. public:
  52.     virtual ~TObject() = 0;
  53. #else
  54.     inline TObject() : fReferenceCount(0) {}
  55. public:
  56.     virtual ~TObject() = 0 {};
  57. #endif
  58.  
  59.     inline void            NewReference()        const;
  60.     inline void            DeleteReference()    const;
  61.     inline long         GetReferenceCount()    const;
  62.  
  63. protected:
  64.     virtual void        Initialize();    // called by factory after construction
  65.     virtual void        Finalize();        // called just before destruction
  66.     virtual void        Delete();        // force a delete - warns if refcount != 1
  67.  
  68.     virtual TObject*    DeepClone()        const;    // create an exact copy on this object
  69.  
  70. public:
  71.  
  72. #if qDebug
  73.     virtual const char*    GetClassName() const;
  74.     virtual const void*    GetBaseAddress() const;
  75.     virtual void        WriteToDebugger(bool flush = true) const;
  76. #else
  77.     inline    void        WriteToDebugger(bool flush = true) const    { flush; }
  78. #endif
  79.  
  80.     // Helper functions for the templates below
  81.  
  82.     static void            NilObjectReference();
  83.  
  84.     static void            InitializeObject(const TObject* obj);
  85.     static void            FinalizeObject(const TObject* obj);
  86.     static void            DeleteObject(const TObject* obj);
  87.  
  88.     static TObject*        NewObjectRef(const TObject* obj);
  89.     static TObject&        NewObjectRef(const TObject& obj);
  90.     static TObject*        DeleteObjectRef(const TObject* obj);
  91.     static inline void    DeleteObjectRef(const TObject& obj) { DeleteObjectRef(&obj); }
  92.     static TObject*        SwapObjectRef(const TObject* dec, const TObject* inc);
  93.     static TObject&        SwapObjectRef(const TObject& dec, const TObject& inc);
  94.     // Atomically increments the refcount of one object and decrements another
  95.     // (either may be nil as well).  This is used to support reference-counted
  96.     // assignments
  97.  
  98. };
  99.  
  100.  
  101.  
  102. // Helper class for when a TObject is declared on the stack -- the constructor initializes
  103. // the object, the destructor finalizes it (with all appropriate bookkeeping)
  104.  
  105. class ObjectInitializer
  106. {
  107.     const TObject&    fObject;
  108.  
  109. public:
  110.     ObjectInitializer(const TObject& obj);
  111.     ~ObjectInitializer();
  112. };
  113.  
  114. inline void TObject::NewReference()    const
  115. {
  116.     long count = fReferenceCount;
  117.     
  118.     if (count <= 0)
  119.         InitializeObject(this);
  120.     else
  121.         const_cast<TObject*>(this)->fReferenceCount = count + 1;
  122. }
  123.  
  124. inline void TObject::DeleteReference()    const
  125. {
  126.     long count = fReferenceCount - 1;
  127.     
  128.     if (count <= 0)
  129.         DeleteObject(this);
  130.     else
  131.         const_cast<TObject*>(this)->fReferenceCount = count;
  132. }
  133.  
  134. inline long TObject::GetReferenceCount() const
  135. {
  136.     return fReferenceCount;
  137. }
  138.  
  139. #if 0
  140.  
  141. // helper functions for subclasses -- this would be member templates if
  142. // Codewarrior allowed them -- they should be simple enough that they will 
  143. // always inline, but you never know
  144.  
  145. template<class T>
  146. inline T* NewObjectRef(T* obj)
  147. {
  148. //    if (obj != nil) CodeWarrior won't inline this!!!!
  149.     {
  150.         Object::NewObjectRef(obj);
  151.     }
  152.  
  153.     return obj;    
  154. }
  155. /*
  156. template<class T>
  157. inline T& NewObjectRef(T& obj)
  158. {
  159. //    if (obj != nil) CodeWarrior won't inline this!!!!
  160.     {
  161.         Object::NewObjectRef(obj);
  162.     }
  163.  
  164.     return obj;    
  165. }
  166. */
  167. template<class T>
  168. inline T* DeleteObjectRef(T* obj)
  169. {
  170. //    if (obj) CodeWarrior won't inline this!!!!
  171.     {
  172.         Object::DeleteObjectRef(obj);
  173.     }
  174.  
  175.     return nil;    
  176. }
  177.  
  178. template<class T, class T1>
  179. inline T* SwapObjectRef(T1* inc, T* dec)
  180. {
  181. //    const TObject* inc1 = inc;
  182. //    const TObject* dec1 = dec;
  183. //
  184. //    if (inc1 != dec1)
  185.     {
  186.         Object::SwapObjectRef(inc, dec);
  187.     }
  188.     
  189.     return inc;    
  190. }
  191.  
  192. template<class T, class T1>
  193. inline T& SwapObjectRef(T1& inc, T& dec)
  194. {
  195. //    const TObject* inc1 = inc;
  196. //    const TObject* dec1 = dec;
  197. //
  198. //    if (inc1 != dec1)
  199.     {
  200.         Object::SwapObjectRef(inc, dec);
  201.     }
  202.     
  203.     return inc;    
  204. }
  205.  
  206. #endif
  207.  
  208. #endif // __OBJECT__
  209.